﻿using CSRedis;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Snowflake.Core;
using Swashbuckle.AspNetCore.Annotations;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using XsqTech.SmartOA.Dtos.DTO;
using XsqTech.SmartOA.IService;
using XsqTech.SmartOA.Service.DTO;

namespace XsqTech.SmartOA.Application.Controllers
{
    /// <summary>
    /// JWT生成
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class JwtController : ControllerBase
    {
        IUserService _userService;
        readonly IConfiguration _configuration;
        /// <summary>
        /// 构造函数
        /// </summary>
        public JwtController(IUserService userService, IConfiguration configuration)
        {
            _userService = userService;
            _configuration = configuration;
        }

        /// <summary>
        /// Token的生成
        /// </summary>
        /// <returns></returns>
        [HttpGet("JwtToken")]
        [SwaggerOperation(Summary = "JWTToken的生成")]
        public IActionResult JwtToken()
        {
            List<Claim> claims = new List<Claim>() { new Claim(ClaimTypes.Name, "你好世界") };
            //自定义签名
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("q12w3eds4dfd5rg68sduhgytjajjy8ii9sadjd"));//108位
            var Credentials = new SigningCredentials(key, algorithm: "HS256");

            var token = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(
                issuer: "夏苏强", //发行人
                audience: "所有人",//受众
                claims: claims,//声明
                notBefore: DateTime.Now,//生效时间
                expires: DateTime.Now.AddHours(2),//过期时间(两小时过期)
                signingCredentials: Credentials//签名(自定义)
                );
            var jwttoken = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler().WriteToken(token);

            return Ok(jwttoken);
        }

        [HttpPost("UserLogin")]
        [AllowAnonymous]//允许匿名访问
        [SwaggerOperation(Summary = "用户登录")]
        public IActionResult Login(UserLogin loginDto)
        {
            //进行模型验证
            if (!ModelState.IsValid)
            {
                //如果参数错误直接返回400
                return BadRequest();
            }
            //获取用户 result=结果
            var result = _userService.GetLogin(loginDto);
            if (result != null)
            {
                //荷载信息
                List<Claim> claims = new()
                {
                    new Claim(ClaimTypes.Name,loginDto.Name!),
                    //new Claim(ClaimTypes.NameIdentifier,usersDto)
                };
                //签名秘钥(自定义)
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("qazwsxedcrfvtgbyhnujmikolp"));
                //对秘钥加密
                var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                //过去时间
                DateTime dateTime = DateTime.Now.AddSeconds(2 * 3600);//以秒为单位
                                                                      //实例化JWT安全令牌对象
                var JwtTokens = new JwtSecurityToken(

                     issuer: "CS",//发布者
                     audience: "everyone",//受众(发给谁去使用)
                     claims: claims,//发起人
                     expires: dateTime,//过期时间
                     signingCredentials: credentials//秘钥
                    );
                //序列化JWT令牌,从而得到一个字符串
                string strToken = new JwtSecurityTokenHandler().WriteToken(JwtTokens);

                //拿到redis配置
                string SnowTokenCard = new IdWorker(1, 1).NextId().ToString();
                CSRedisClient cSRedis = new(_configuration.GetSection("RedisConn").Value);
                cSRedis.Set(SnowTokenCard, loginDto, 3 * 24 * 3600);

                return Ok(new ResponseModel { Code = State.请求成功, Data = result, Message = "用户登录成功", Token = strToken, NewToken = SnowTokenCard });
            }
            else
            {
                return Ok(new ResponseModel { Code = State.请求失败, Data = result, Message = "用户登录失败" });
            }
        }
    }
}
